#![feature(type_alias_impl_trait)]

use actix_cors::Cors;
use actix_web::{middleware, App, HttpServer};
use fast_log::{
    consts::LogSize, plugin::file_split::RollingType, plugin::packer::GZipPacker, Config,
};
use log::LevelFilter;
use services::{license, verify};
use std::net::SocketAddr;
use volo_grpc::server::{Server, ServiceBuilder};

mod common;
mod handlers;
mod services;
mod tables;
mod utils;

#[tokio::main]
async fn main() {
    fast_log::init(
        Config::new()
            .chan_len(Some(100000))
            .level(LevelFilter::Debug)
            .console()
            .file_split(
                "logs/",
                LogSize::KB(50),
                RollingType::KeepNum(5),
                GZipPacker {},
            ),
    )
        .unwrap();

    utils::mysql::init_pool().await;

    // use tables::menu::TbMenu;

    // let tables = vec![
    //     TbMenu {
    //         id: Some(1),
    //         path: "/welcome".into(),
    //         name: "home".into(),
    //         title: "首页".into(),
    //         icon: None,
    //         parent_id: None,
    //         hidden: false,
    //         sort: 1,
    //     },
    //     TbMenu {
    //         id: Some(2),
    //         path: "/system".into(),
    //         name: "setting".into(),
    //         title: "系统设置".into(),
    //         icon: None,
    //         parent_id: None,
    //         hidden: false,
    //         sort: 2,
    //     },
    //     TbMenu {
    //         id: Some(3),
    //         path: "/business".into(),
    //         name: "business".into(),
    //         title: "业务".into(),
    //         icon: None,
    //         parent_id: None,
    //         hidden: false,
    //         sort: 3,
    //     },
    //     TbMenu {
    //         id: Some(4),
    //         path: "/system/role".into(),
    //         name: "roleSetting".into(),
    //         title: "角色设置".into(),
    //         icon: None,
    //         parent_id: Some(2),
    //         hidden: false,
    //         sort: 4,
    //     },
    //     TbMenu {
    //         id: Some(5),
    //         path: "/system/menu".into(),
    //         name: "menuSetting".into(),
    //         title: "菜单设置".into(),
    //         icon: None,
    //         parent_id: Some(2),
    //         hidden: false,
    //         sort: 5,
    //     },
    //     TbMenu {
    //         id: Some(6),
    //         path: "/system/api".into(),
    //         name: "apiSetting".into(),
    //         title: "Api设置".into(),
    //         icon: None,
    //         parent_id: Some(2),
    //         hidden: false,
    //         sort: 6,
    //     },
    //     TbMenu {
    //         id: Some(7),
    //         path: "/system/log".into(),
    //         name: "backendLog".into(),
    //         title: "后台日志".into(),
    //         icon: None,
    //         parent_id: Some(2),
    //         hidden: false,
    //         sort: 7,
    //     },
    //     TbMenu {
    //         id: Some(8),
    //         path: "/business/user".into(),
    //         name: "userSetting".into(),
    //         title: "用户设置".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 8,
    //     },
    //     TbMenu {
    //         id: Some(9),
    //         path: "/business/applog".into(),
    //         name: "engineLog".into(),
    //         title: "引擎日志".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 9,
    //     },
    //     TbMenu {
    //         id: Some(10),
    //         path: "/business/license".into(),
    //         name: "licenseSetting".into(),
    //         title: "授权管理".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 10,
    //     },
    //     TbMenu {
    //         id: Some(11),
    //         path: "/business/app".into(),
    //         name: "appSetting".into(),
    //         title: "应用设置".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 11,
    //     },
    //     TbMenu {
    //         id: Some(12),
    //         path: "/business/netpoint".into(),
    //         name: "netpointSetting".into(),
    //         title: "网点设置".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 12,
    //     },
    //     TbMenu {
    //         id: Some(13),
    //         path: "/business/attend".into(),
    //         name: "attendSetting".into(),
    //         title: "考勤管理".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 13,
    //     },
    //     TbMenu {
    //         id: Some(14),
    //         path: "/business/device".into(),
    //         name: "deviceSetting".into(),
    //         title: "设备设置".into(),
    //         icon: None,
    //         parent_id: Some(3),
    //         hidden: false,
    //         sort: 14,
    //     },
    // ];

    // let _ = TbMenu::insert_batch(&mut utils::mysql::MYSQL.clone(), &tables, 10).await;

    // use tables::role::TbRole;

    // let tables = vec![
    //     TbRole {
    //         id: Some(1),
    //         name: "超级管理员".into(),
    //         menu_ids: Some(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]),
    //         api_ids: Some(vec![
    //             1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
    //             24, 25, 26, 27, 28, 29, 30, 31, 32,
    //         ]),
    //     },
    //     TbRole {
    //         id: Some(2),
    //         name: "管理员".into(),
    //         menu_ids: Some(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]),
    //         api_ids: Some(vec![
    //             1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
    //         ]),
    //     },
    //     TbRole {
    //         id: Some(3),
    //         name: "普通用户".into(),
    //         menu_ids: Some(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
    //         api_ids: Some(vec![
    //             1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
    //         ]),
    //     },
    // ];

    // let _ = TbRole::insert_batch(&mut utils::mysql::MYSQL.clone(), &tables, 10).await;

    // use tables::api::TbApi;

    // let tables = vec![
    //     TbApi {
    //         id: Some(1),
    //         path: "/api/account/login".into(),
    //         description: "登录".into(),
    //         apigroup: "账号".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(2),
    //         path: "/api/account/logout".into(),
    //         description: "登出".into(),
    //         apigroup: "账号".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(3),
    //         path: "/api/app".into(),
    //         description: "获取应用信息".into(),
    //         apigroup: "应用".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(4),
    //         path: "/api/app".into(),
    //         description: "添加应用".into(),
    //         apigroup: "应用".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(5),
    //         path: "/api/app".into(),
    //         description: "删除应用".into(),
    //         apigroup: "应用".into(),
    //         method: "DELETE".into(),
    //     },
    //     TbApi {
    //         id: Some(6),
    //         path: "/api/applog".into(),
    //         description: "获取引擎日志".into(),
    //         apigroup: "引擎日志".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(7),
    //         path: "/api/attend".into(),
    //         description: "获取考勤信息".into(),
    //         apigroup: "考勤".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(8),
    //         path: "/api/device".into(),
    //         description: "获取设备信息".into(),
    //         apigroup: "设备".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(9),
    //         path: "/api/device".into(),
    //         description: "更新设备信息".into(),
    //         apigroup: "设备".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(10),
    //         path: "/api/device".into(),
    //         description: "删除设备".into(),
    //         apigroup: "设备".into(),
    //         method: "DELETE".into(),
    //     },
    //     TbApi {
    //         id: Some(11),
    //         path: "/api/log".into(),
    //         description: "获取后台日志".into(),
    //         apigroup: "后台日志".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(12),
    //         path: "/api/netpoint".into(),
    //         description: "获取网点信息".into(),
    //         apigroup: "网点".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(13),
    //         path: "/api/netpoint".into(),
    //         description: "更新网点信息".into(),
    //         apigroup: "网点".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(14),
    //         path: "/api/netpoint".into(),
    //         description: "删除网点".into(),
    //         apigroup: "网点".into(),
    //         method: "DELETE".into(),
    //     },
    //     TbApi {
    //         id: Some(15),
    //         path: "/api/user".into(),
    //         description: "获取用户信息".into(),
    //         apigroup: "用户".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(16),
    //         path: "/api/user".into(),
    //         description: "添加用户".into(),
    //         apigroup: "用户".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(17),
    //         path: "/api/user".into(),
    //         description: "删除用户".into(),
    //         apigroup: "用户".into(),
    //         method: "DELETE".into(),
    //     },
    //     TbApi {
    //         id: Some(18),
    //         path: "/api/user/current".into(),
    //         description: "获取当前用户信息".into(),
    //         apigroup: "用户".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(19),
    //         path: "/api/user/all".into(),
    //         description: "获取所有用户信息".into(),
    //         apigroup: "用户".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(20),
    //         path: "/api/role".into(),
    //         description: "获取角色信息".into(),
    //         apigroup: "角色".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(21),
    //         path: "/api/role".into(),
    //         description: "添加角色".into(),
    //         apigroup: "角色".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(22),
    //         path: "/api/role".into(),
    //         description: "更新角色".into(),
    //         apigroup: "角色".into(),
    //         method: "PUT".into(),
    //     },
    //     TbApi {
    //         id: Some(23),
    //         path: "/api/role".into(),
    //         description: "删除角色".into(),
    //         apigroup: "角色".into(),
    //         method: "DELETE".into(),
    //     },
    //     TbApi {
    //         id: Some(24),
    //         path: "/api/menu".into(),
    //         description: "获取所有菜单信息".into(),
    //         apigroup: "菜单".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(25),
    //         path: "/api/menu".into(),
    //         description: "添加菜单".into(),
    //         apigroup: "菜单".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(26),
    //         path: "/api/menu".into(),
    //         description: "更新菜单".into(),
    //         apigroup: "菜单".into(),
    //         method: "PUT".into(),
    //     },
    //     TbApi {
    //         id: Some(27),
    //         path: "/api/menu".into(),
    //         description: "删除菜单".into(),
    //         apigroup: "菜单".into(),
    //         method: "DELETE".into(),
    //     },
    //     TbApi {
    //         id: Some(28),
    //         path: "/api/api/all".into(),
    //         description: "获取所有API信息".into(),
    //         apigroup: "API".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(29),
    //         path: "/api/api".into(),
    //         description: "获取API信息".into(),
    //         apigroup: "API".into(),
    //         method: "GET".into(),
    //     },
    //     TbApi {
    //         id: Some(30),
    //         path: "/api/api".into(),
    //         description: "添加API".into(),
    //         apigroup: "API".into(),
    //         method: "POST".into(),
    //     },
    //     TbApi {
    //         id: Some(31),
    //         path: "/api/api".into(),
    //         description: "更新API".into(),
    //         apigroup: "API".into(),
    //         method: "PUT".into(),
    //     },
    //     TbApi {
    //         id: Some(32),
    //         path: "/api/api".into(),
    //         description: "删除API".into(),
    //         apigroup: "API".into(),
    //         method: "DELETE".into(),
    //     },
    // ];

    // let _ = TbApi::insert_batch(&mut utils::mysql::MYSQL.clone(), &tables, 10).await;

    handlers::menu::init_menus()
        .await
        .expect("init menus error");
    handlers::api::init_apis().await.expect("init apis error");
    handlers::role::init_roles()
        .await
        .expect("init roles error");

    let volo_server = tokio::spawn(async move {
        let addr: SocketAddr = utils::config::CONFIG.volo_addr().parse().unwrap();
        let addr = volo::net::Address::from(addr);

        Server::new()
            .add_service(
                ServiceBuilder::new(volo_gen::wmplatform3::LicenseServiceServer::new(license::S))
                    .build(),
            )
            .add_service(
                ServiceBuilder::new(volo_gen::wmplatform3::VerifyServiceServer::new(verify::S))
                    .build(),
            )
            .run(addr)
            .await
            .unwrap();
    });

    let addr = utils::config::CONFIG.api_addr();

    log::info!("starting HTTP api server at http://{}", addr);

    let _ = HttpServer::new(move || {
        App::new()
            .wrap(Cors::permissive())
            .wrap(middleware::NormalizePath::trim())
            .wrap(middleware::Logger::default())
            .configure(handlers::api_routes)
    })
        .bind(addr)
        .expect("failed to start api web server")
        .run()
        .await;

    let _ = volo_server.await;
}
